import java.util.Scanner;

//一般来说一个java文件只有一个类,但是也可以在public class上再定义一个类，但是使用public修饰的类只有一个，其他类的类型:class 类名(大驼峰)
public class JavaClassesAndObjects {
    private String name;
    private int age;    //只要是private就是用get和set方法来获取或者修改这个成员变量

    private static String classRoom="java教室";  //就地初始化    static修饰的成员变量，叫做静态成员变量，是所有对象共享的  方法中不能创建static修饰的类变量

    public static String getClassRoom() {   //成员变量是静态的就是用静态的成员方法，否则就还要新建一个对象
        return classRoom;
    }

    public static void setClassRoom(String classRoom) {
        JavaClassesAndObjects.classRoom = classRoom;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    //当出现两个构造方法的时候就叫做构造方法的重载
    public JavaClassesAndObjects() {

        this("hei",20);   //调用了下面的那个构造方法 ，不能形成环
    }

    {
        this.name="haha";  //在调用构造方法之前执行这部分代码，和静态代码块不一样的是只要实例化了一个对象就会，即能够多次执行
        System.out.println("非静态代码块/实例代码块/构造代码块!->一般用来初始化非静态的数据成员");
    }

    static {
        System.out.println("静态代码块-》初始化静态的数据成员/提前准备一些数据"); //静态代码块最先执行，构造代码块在它之后执行，构造方法最后执行
        //只要类被加载就会执行，不需要new对象
    }
    public JavaClassesAndObjects(String name,int age) {
        //this();    不能同时调用this（）
        this.name=name;
        this.age=age;
        //this.sleep();
    }
    public void setData(JavaClassesAndObjects this,String name,int age) {
        this.name=name;   //不加this那么就是形参名自己给自己赋值
        this.age=age;     //加上this就表示给这个引用指向对象的成员属性赋值
    }
    public void eat() {
        //func3(); 可以在非静态成员方法中调用静态成员方法
        System.out.println("吃饭");
    }
    public  void sleep() {

        System.out.println(age+"岁的"+name+"睡觉");
    }

    public static void func() {
        //在静态方法内部，不能使用非静态方法，要通过新建对象去调用
        //在静态方法内部，不能使用非静态数据成员
        JavaClassesAndObjects p1=new JavaClassesAndObjects();
        System.out.println(p1.name);
        p1.eat();
    }

    public static void func2() {
        JavaClassesAndObjects.func();
        func();  //这两种方式都是正确的
        System.out.println("静态成员方法/类方法");
    }


    @Override   //叫做注解
    public String toString() {
        return "JavaClassesAndObjects{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public static void func3() {

        //执行不需要条件（不建议这样使用）
        {
            System.out.println("定义在方法内部的代码块，就是普通代码块");
        }
    }
    public static void main(String[] args) {
        //通过关键字new实例化了一个类对象
        //person的数据类型
        JavaClassesAndObjects person=new JavaClassesAndObjects();
        person.age=10;
        person.name="张三";   //成员变量不初始化会有默认值   引用.xxxx 如果引用为null，那么就会发生空指针异常
        person.sleep();

        JavaClassesAndObjects person1=new JavaClassesAndObjects("王五",16);
        System.out.println(person1.age);

        JavaClassesAndObjects person3=new JavaClassesAndObjects();
        System.out.println(person3.getAge());
        System.out.println(person3.getName());
        System.out.println(person.classRoom);
        System.out.println(person1.classRoom);
        System.out.println(person3.classRoom);
        System.out.println(JavaClassesAndObjects.classRoom);


        JavaClassesAndObjects person4=null;   //不指向任何对象
        System.out.println(person4.classRoom);   //因为类型是Person 所以访问和指不指向对象没有关系
        JavaClassesAndObjects.func();

        System.out.println(getClassRoom());
        setClassRoom("123");
        System.out.println(getClassRoom());
        System.out.println(classRoom);

        func3();

        System.out.println(person3);  //如果你想输出一个对象的引用的值的时候，如果没有自己写的tostring方法，那么就会调用object这个类的方法
        //如果自己写了，就调用自己写的tostring方法，这样直接输出一个对象的引用值得时候，就不会是一个地址值了，会根据你写的tostring方法来输出
    }
}




//exercise
class Student {
    private String name;
    private int age;

    public static String gender;

    public Student() {
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public static String getGender() {
        return gender;
    }

    @Override
    public String toString() {
        System.out.println("aaa");
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender=‘"+gender+'\''+
                '}';
    }
    public Student(String name, int age, String gender) {
        this.name = name;
        this.age = age;
        Student.gender = gender;
    }

    public static void main(String[] args) {
        Student student = new Student("123", 15, "男");
        System.out.println(getGender());
        Student student2 = new Student();
    }

    static {
        System.out.println("2");
    }
}

class Exercise {
    public static void main(String[] args) {
        Scanner scan=new Scanner(System.in);
        String name=scan.nextLine();
        int age=scan.nextInt();
        scan.nextLine();
        String gender=scan.nextLine();
        Student student=new Student(name,age,gender);  //如果另一个类中的构造方法被private修饰，那么其他类中就不能访问这个构造方法
        System.out.println(student.getAge());
        System.out.println(student.getName());
        System.out.println(student);
    }
}
